// 使用动态导入和更安全的错误处理
let SockJS = null
let Stomp = null
let ElMessage = null

// 延迟加载依赖，避免在模块导入时就出错
const loadDependencies = async () => {
  try {
    if (!SockJS) {
      const sockjsModule = await import('sockjs-client')
      SockJS = sockjsModule.default || sockjsModule
    }
    if (!Stomp) {
      const stompModule = await import('@stomp/stompjs')
      Stomp = stompModule.Stomp
    }
    if (!ElMessage) {
      const elementModule = await import('element-plus')
      ElMessage = elementModule.ElMessage
    }
    return true
  } catch (error) {
    console.error('加载WebSocket依赖失败:', error)
    return false
  }
}

class WebSocketClient {
  constructor() {
    this.stompClient = null
    this.connected = false
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 5000
    this.subscriptions = new Map()
    this.messageHandlers = new Map()
    this.dependenciesLoaded = false
  }

  /**
   * 连接WebSocket服务器
   */
  async connect() {
    try {
      // 首先加载依赖
      if (!this.dependenciesLoaded) {
        const loaded = await loadDependencies()
        if (!loaded) {
          throw new Error('WebSocket依赖加载失败')
        }
        this.dependenciesLoaded = true
      }

      if (this.connected) {
        console.log('WebSocket已连接')
        return Promise.resolve()
      }

      return new Promise((resolve, reject) => {
        try {
          // 创建SockJS连接
          let wsUrl
          if (import.meta.env.VITE_API_BASE_URL) {
            // 如果有配置API基础URL，则从中提取WebSocket URL
            wsUrl = import.meta.env.VITE_API_BASE_URL.replace('/api', '') + '/ws'
          } else {
            // 检查当前页面的端口，如果是8088（前端开发服务器），则连接到8080（后端）
            const currentPort = window.location.port
            if (currentPort === '8088') {
              wsUrl = 'http://localhost:8080/ws'
            } else {
              // 否则使用当前域名
              wsUrl = `${window.location.protocol}//${window.location.hostname}:${window.location.port || 80}/ws`
            }
          }
          console.log('WebSocket连接URL:', wsUrl)
          
          const socket = new SockJS(wsUrl)
          this.stompClient = Stomp.over(socket)

          // 配置STOMP客户端
          this.stompClient.configure({
            // 连接成功回调
            onConnect: (frame) => {
              console.log('WebSocket连接成功:', frame)
              this.connected = true
              this.reconnectAttempts = 0
              
              // 订阅全局配额更新
              this.subscribeToGlobalQuota()
              
              resolve()
            },

            // 连接错误回调
            onStompError: (frame) => {
              console.error('WebSocket连接错误:', frame)
              this.connected = false
              reject(new Error('WebSocket连接失败: ' + (frame?.headers?.message || '未知错误')))
            },

            // WebSocket错误回调
            onWebSocketError: (error) => {
              console.error('WebSocket底层错误:', error)
              this.connected = false
              reject(new Error('WebSocket底层连接失败'))
            },

            // 连接断开回调
            onDisconnect: () => {
              console.log('WebSocket连接断开')
              this.connected = false
              this.handleReconnect()
            },

            // 关闭调试日志
            debug: (str) => {
              if (import.meta.env.MODE === 'development') {
                console.log('STOMP Debug:', str)
              }
            }
          })

          // 激活连接
          this.stompClient.activate()

        } catch (error) {
          console.error('创建WebSocket连接失败:', error)
          reject(error)
        }
      })
    } catch (error) {
      console.error('WebSocket连接准备失败:', error)
      throw error
    }
  }

  /**
   * 断开WebSocket连接
   */
  disconnect() {
    try {
      if (this.stompClient && this.connected) {
        // 取消所有订阅
        this.subscriptions.forEach((subscription) => {
          try {
            subscription.unsubscribe()
          } catch (error) {
            console.error('取消订阅失败:', error)
          }
        })
        this.subscriptions.clear()
        
        // 断开连接
        this.stompClient.deactivate()
        this.connected = false
        console.log('WebSocket连接已断开')
      }
    } catch (error) {
      console.error('断开WebSocket连接时出错:', error)
    }
  }

  /**
   * 处理重连逻辑
   */
  handleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++
      console.log(`尝试重连WebSocket (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
      
      setTimeout(() => {
        this.connect().catch((error) => {
          console.error('重连失败:', error)
        })
      }, this.reconnectInterval)
    } else {
      console.error('WebSocket重连失败，已达到最大重试次数')
      if (ElMessage) {
        ElMessage.error('实时连接已断开，请刷新页面重试')
      }
    }
  }

  /**
   * 订阅全局配额更新
   */
  subscribeToGlobalQuota() {
    if (!this.connected || !this.stompClient) return

    try {
      const subscription = this.stompClient.subscribe('/topic/global-quota-update', (message) => {
        try {
          const data = JSON.parse(message.body)
          console.log('收到全局配额更新:', data)
          
          // 触发全局配额更新事件
          this.triggerHandler('globalQuotaUpdate', data)
        } catch (error) {
          console.error('解析全局配额更新消息失败:', error)
        }
      })

      this.subscriptions.set('globalQuota', subscription)
    } catch (error) {
      console.error('订阅全局配额更新失败:', error)
    }
  }

  /**
   * 订阅用户特定的配额更新
   */
  subscribeToUserQuota(userId) {
    if (!this.connected || !this.stompClient) return

    try {
      const subscription = this.stompClient.subscribe(`/user/${userId}/queue/quota-update`, (message) => {
        try {
          const data = JSON.parse(message.body)
          console.log('收到用户配额更新:', data)
          
          // 触发用户配额更新事件
          this.triggerHandler('userQuotaUpdate', data)
        } catch (error) {
          console.error('解析用户配额更新消息失败:', error)
        }
      })

      this.subscriptions.set('userQuota', subscription)
    } catch (error) {
      console.error('订阅用户配额更新失败:', error)
    }
  }

  /**
   * 订阅任务状态更新
   */
  subscribeToTaskStatus(userId) {
    if (!this.connected || !this.stompClient) return

    try {
      const subscription = this.stompClient.subscribe(`/user/${userId}/queue/task-status`, (message) => {
        try {
          const data = JSON.parse(message.body)
          console.log('收到任务状态更新:', data)
          
          // 触发任务状态更新事件
          this.triggerHandler('taskStatusUpdate', data)
        } catch (error) {
          console.error('解析任务状态更新消息失败:', error)
        }
      })

      this.subscriptions.set('taskStatus', subscription)
    } catch (error) {
      console.error('订阅任务状态更新失败:', error)
    }
  }

  /**
   * 注册消息处理器
   */
  onMessage(event, handler) {
    try {
      if (!this.messageHandlers.has(event)) {
        this.messageHandlers.set(event, [])
      }
      this.messageHandlers.get(event).push(handler)
    } catch (error) {
      console.error('注册消息处理器失败:', error)
    }
  }

  /**
   * 移除消息处理器
   */
  offMessage(event, handler) {
    try {
      if (this.messageHandlers.has(event)) {
        const handlers = this.messageHandlers.get(event)
        const index = handlers.indexOf(handler)
        if (index > -1) {
          handlers.splice(index, 1)
        }
      }
    } catch (error) {
      console.error('移除消息处理器失败:', error)
    }
  }

  /**
   * 触发消息处理器
   */
  triggerHandler(event, data) {
    try {
      if (this.messageHandlers.has(event)) {
        this.messageHandlers.get(event).forEach(handler => {
          try {
            handler(data)
          } catch (error) {
            console.error(`处理${event}事件时出错:`, error)
          }
        })
      }
    } catch (error) {
      console.error('触发消息处理器失败:', error)
    }
  }

  /**
   * 获取连接状态
   */
  isConnected() {
    return this.connected
  }

  /**
   * 安全地发送消息
   */
  safeSend(destination, body) {
    try {
      if (this.connected && this.stompClient) {
        this.stompClient.publish({
          destination: destination,
          body: JSON.stringify(body)
        })
        return true
      } else {
        console.warn('WebSocket未连接，无法发送消息')
        return false
      }
    } catch (error) {
      console.error('发送WebSocket消息失败:', error)
      return false
    }
  }
}

// 创建全局WebSocket客户端实例
const wsClient = new WebSocketClient()

export default wsClient 